iT邦幫忙

2022 iThome 鐵人賽

DAY 10
3

Day10 自己做一個價值幾十萬的動態網站

第十課:了解Css Grid介紹與應用,/:id 與params,完成製作hotel Page

bookingchallenge.day10.version

跳轉去hotelPage前置作業

hotelsList Page UI製作也要進到尾聲,要製作最後一個hotelPage之前,我們要先把畫面帶過去hotel Page,所以回到App.jsx那邊,畫面應該如下:

之前也有提到過 /:id 是api 會到時候會需要用到的params,所以這邊我們可以先慢慢了解他,以一般url輸入,為了跳轉去hotel page分頁你可以隨便亂打id只要是數字就可以了,如輸入以下url

http://localhost:3000/hotels/dadda132


除了輸入url網址到分頁,我們也要新增link到searchItem的button裡面

<Link to="/hotels/imhotelrandomid123">
      <button className='btn' >查看客房供應情況</button>
</Link>

這邊imhotelrandomid123未來會替換成真的hotel資料的id,這邊算是先預告先放著。

並一樣先導入我們到哪裡都會有的Navbar

並做到這邊後就可以來製作hotelPage UI 下面是稍微會帶到css設計概念,這邊可能設計的有點亂,所以將稍微交代一下,如對css很熟悉的人可部分略過,

hotelPage UI製作

首先不免俗的分析UI,進行到這邊大家都可以用自己習慣的設計去styling

相關hotel div起頭(下面會附完整得github連結)

<div className='hotel'>
 <Navbar />
 <div className="HotelContainer">
   <div className="HotelWrapper">
     <div className="HotelHeaderBtn">
       <button>資訊 & 房價</button>
       <button>設施</button>
       <button>訂房須知</button>
       <button>房客評價</button>
     </div>
     <div className="hotelTitle">
     </div>
     <div className="hotelImgWrapper">
     </div>
     <div className="hotelDes">
     </div>
   </div>
 </div>
 <Footer />
</div>

與container wrapper scss

.HotelContainer {
    display: flex;
    justify-content: center;
    padding: 20px;//一樣往內縮
    .HotelWrapper {
        max-width: 1024px;
        width: 100%;
        display: flex;
        flex-direction: column;
        gap: 10px; //這四塊大div都各自取件間距
    }
}

與HotelHeaderBtn

.HotelHeaderBtn {
    display: flex;
    gap: 3px;
    button {
        border: none;
        background-color: rgba(53, 164, 127, 0.5);
        padding: 10px 20px;
        font-size: 16px;
        border-radius: 2px;
        color: rgb(36, 104, 81);
        &:hover {
            color: black;
        }
    }
}

hotelPage Title

與將重點先放在title解釋上

hotelTitle.div

<div className="hotelTitle">
   <div className="titleLeft">
     <span className="type">飯店</span>
     <span className='hotelName'>台南微醺文旅</span>
     <span className='recommend'><span className="recommendSvg"><FontAwesomeIcon icon={faPeopleGroup} /></span>推薦四人住宿</span>   
     <div className="address"><FontAwesomeIcon icon={faLocationDot} /> 台南中西區No. 28 Dade Street <a>地理位置超棒-顯示地圖</a>
     </div>
   </div>
   <div className="titleRight">
     <button className="reservationBtn">現在就預訂</button>
     <p> <FontAwesomeIcon icon={faHeartCircleCheck} /> <span>買貴退差價</span></p>
   </div>
</div>

值得一提的是是titleLeft中是以三個span與一個div組成,利用div會自動換行的效果來分行,並用vertical-align讓span可以置中,與特別的"推薦幾人居住",有更改vertical-align: bottom;讓它感覺比較對齊,這邊可以改動試試看

.titleLeft {
        span {
            margin-right: 5px;
            vertical-align: middle;//所有span的對齊以文字為主向下
        }
        .type {
            color: white;
            background-color: #00d8ff;
            border-radius: 2px;
            padding: 2px;
        }
        .hotelName {
            font-weight: 600;
            font-size: 20px;
        }
        .recommend {
            vertical-align: bottom;//以文字為主向下對齊就不使用middle了
            background-color: #cbe5d8;
            font-size: 12px;
            border-radius: 15px;
            padding: 5px 10px 5px 0px;//0px是為了讓svg小球的下層左邊的區塊內縮
            svg {
                width: 15px;
                height: 15px;
                padding: 2px;
                color: var(--primary-color);
                background-color: #fff;
                border: 1px solid black;
                border-radius: 50%;
            }
        }
         .address {
            font-size: 16px;
            a{
                font-size: 12px;
                color: rgb(83, 129, 254);
            }
        }
    }

大致完成這邊後,進到第三個大div,中間照片區域hotelImgWrapper

img map建立簡單照片array

這邊一樣要使用到map來排列照片,特別是不用特別在data.js作資料array,我們也可以直接在上面列資料Array,因為指涉及需要img URL
所以可以很快的列出照片,需要完整照片data.js我都會放在今天的github hotel.jsx 裡面。也可以自己抓自己想要的資料。

const photos = [
    {
      src: "https://cf.bstatic.com/xdata/images/hotel/max1280x900/261707778.jpg?k=56ba0babbcbbfeb3d3e911728831dcbc390ed2cb16c51d88159f82bf751d04c6&o=&hp=1",
    },
    {
      src: "https://cf.bstatic.com/xdata/images/hotel/max1280x900/261707367.jpg?k=cbacfdeb8404af56a1a94812575d96f6b80f6740fd491d02c6fc3912a16d8757&o=&hp=1",
    }
  ];

這邊會在hotelImg外面在特別包一層是為了等一下我們會練習gsap的hover彈跳comment視窗,為了彈跳視窗預留一些位置

<div className="hotelImgWrapper">   
    <div className="hotelImg">
      {photos.slice(0, 6).map((item, i) => //不管他再怎麼多 如果剛好有到7張照片就可以觀看更多,並往上加
        i >= 5 ?
          <div className="Imgwrap" key={i}>
            <div className="more"  >{photos.length > 6 ? `+${photos.length - 6}張照片` : "觀看更多"}</div>
            <img src={item.src} alt="img" />
          </div>
          :
          <div className="Imgwrap" key={i}>
            <img src={item.src} alt="img" />
          </div>
      )}
    </div>
</div>

這邊可以看到特別使用slice切割照片前六張(index:0,1,2...,5)是為了到時候可能有很多飯店照片,就展示前六張就好,如果沒有到六張也沒關係,為了事超過六張多切割,我們這樣才能在最後一張放觀看更多,與更多張數等等的,所以這邊div more有點像遮罩在img前面提供資訊與讓她變黑色濾鏡
,這部分才會先用i>=5 來區分前五張與最後一張,並在最後一張使用

{photos.length > 6 ? +${photos.length - 6}張照片` : "觀看更多"} `

代表array資料長度多於六張時,顯示還多了幾張,比如說有九張,這邊就會顯示+3張,如果剛好等於6張就顯示觀看更多,如果小於五張一開始的外面判讀i>=5就連著黑色遮罩都沒有

css Grid介紹與應用

css Grid是一種很適合拿來做照片拼貼的工具,可以自由的課制化與排版,所以除了基本的表格形式,我們將利用它來做顯示飯店照片拼貼的示範,
簡單排版原理介紹介紹

與特殊用法,用在這次照片的排版上 grid-column: 1/3; grid-row: 1/3;



所以套用在實際照片情況就是

所以可以看到各個照片的編號,從上到下,從左到右,如果你也想看編號的話

 {photos.slice(0, 6).map((item, i) => 
    i >= 5 ?
      <div className="Imgwrap" key={i}>
        <div className="more"  >照片編號:{i}</div>
        <img src={item.src} alt="img" />
      </div>
      :
      <div className="Imgwrap" key={i}>
            <div className="more"  >照片編號:{i}</div>
        <img src={item.src} alt="img" />
      </div>
  )}

可以利用做的more遮罩並在div裡面叫出 {i}(照片index) 照片編號:{i}來看自己到時候想要排的資料編號,看完記得恢復原狀。

hotelPage Description 內文與價格

接下來要負責製作畫面下方的住宿內文與價格 最後一個大div.hotelDes
重點可以放在明天的useRef與gsap介紹

<div className="hotelDes">
    <div className="hotelDesText">
        H& 台南微醺文旅 I老宅古城 漫遊體驗I H& tainan weshare hotel
        <br />
        <b>自 2017 年 1 月 10 日開始接待 Booking.com 的旅客入住。</b>
        <br />
        預訂H& 台南微醺文旅 I老宅古城 漫遊體驗I H& tainan weshare hotel可享 Genius 折扣!
        <br />只要登入,預訂此住宿即可省一筆。
        H& 台南微醺文旅 I老宅古城漫遊體驗I H& tainan weshare hotel 位在台南,提供 WiFi(免費)、空調、共用休息室和花園,距離台南孔廟 1.3 公里,距離赤崁樓 1.6 公里。
        部分房型提供附淋浴設施、拖鞋、吹風機和免費盥洗用品的私人衛浴。
        <br />
        H& 台南微醺文旅 I老宅古城漫遊體驗I H& tainan weshare hotel 附近的人氣景點包括藍晒圖文創園區、新光三越台南新天地和林百貨。最近的機場是台南機場,距離這間住宿 10 公里。
        此區為台南的人氣推薦區域(依據真實住客評語)
        獨行旅客特別喜歡這個位置-並給他們的單獨住宿體驗 9.4 分
      <h1>熱門設施</h1>
      <hr />
      <p className='textIcon'><FontAwesomeIcon icon={faWifi} className="wifi" />
        免費無線網路 <FontAwesomeIcon icon={faSmokingBan} />禁菸客房</p>
    </div>
    <div className="hotelDesPrice">
      <h2>住宿特色</h2>
      <p>入住 5 晚的最佳選擇!
        此住宿位於台南評分最高的地區,地理位置評分高達 9.3 分
        深受獨行旅客歡迎</p>
      <h2>TWD 6,240</h2>
      <button>現在就預訂</button>
    </div>
  </div>

與這邊的scss,比較特別的地方只有調整line-height: 2.5; //行距這邊 與在searchList有用過的 height: min-content;

.hotelDes {
    display: flex;
    gap: 20px; //左右兩邊hotelDesText與hotelDesPrice 的間距具
    font-size: 12px;
    margin-top: 10px;
    .hotelDesText {
        line-height: 2.5; //行距
    }
    .hotelDesPrice {
        height: min-content;
        padding: 10px;
        line-height: 1.5;
        display: flex;
        flex-direction: column;
        gap: 15px;
        background-color: rgba(53, 164, 127, 0.5);
        button {
            width: 200px;
            color: white;
            font-size: 20px;
            padding: 5px 10px;
            border: none;
            background-color: rgb(53, 164, 127);
            border-radius: 2px;
            &:hover {
                color: black;
            }
        }
    }
}

結論

這邊大致上了解Css Grid排版與完成hotel頁面後,明天將會將重心放在介紹useRef與gsap並用來製作hotelPage 彈跳視窗製作與其component,一樣是屬於UI介面的特效與動畫解說,這部分完成後將會終於進到nodejs等新篇章。


上一篇
「全端挑戰」單向資料傳遞useLocation與useNavigate實作與介紹,完成homeListPage與其props應用
下一篇
「全端挑戰」useRef與gsap介紹與應用,hover彈跳comment視窗與Slider 滑動banner特效
系列文
自己做一個價值幾十萬的動態網站,學會Mern開發、前台UI設計各式觀念與各式Lib、typescript你該學會的前端技術30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言